package com.fgxia.driver.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fgxia.driver.domain.bo.DriverFreightBo;
import com.fgxia.driver.domain.vo.DriverFreightVo;
import com.fgxia.driver.domain.vo.DriverOrderVo;
import com.fgxia.driver.domain.vo.OrderFreightInfoVo;
import com.fgxia.driver.service.IDriverFreightService;
import com.ruoyi.business.domain.FreightInfo;
import com.ruoyi.business.domain.FreightReceipt;
import com.ruoyi.business.domain.FreightVehicleTrail;
import com.ruoyi.business.domain.OrderInfo;
import com.ruoyi.business.mapper.FreightInfoMapper;
import com.ruoyi.business.mapper.FreightReceiptMapper;
import com.ruoyi.business.mapper.FreightVehicleTrailMapper;
import com.ruoyi.business.mapper.OrderInfoMapper;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.FreightStatus;
import com.ruoyi.common.enums.OrderStatus;
import com.ruoyi.common.enums.SysYesNo;
import com.ruoyi.common.utils.BeanCopyUtils;
import com.ruoyi.common.utils.DateUtils;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * driver freight info service impl
 *
 * 订单状态变化
 * 1.配送中（装货，配送，卸货）
 * 2.待回单（司机提交卸货信息后状态变成待回单）
 * 3.待打款（司机上传回单记录后状态变成待打款）
 * 4.已完成（财务上传打款记录后状态变成已完成）
 * 驱动方式
 *  订单状态的驱动是所有运单全部到下一个状态才到下一个状态
 * @author yyt
 */
@Service
@RequiredArgsConstructor
public class DriverFreightServiceImpl implements IDriverFreightService {

    private final FreightInfoMapper freightInfoMapper;

    private final OrderInfoMapper orderInfoMapper;

    private final FreightVehicleTrailMapper freightVehicleTrailMapper;

    private final FreightReceiptMapper freightReceiptMapper;

    /**
     * 提货
     *
     * @param driverFreightBo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean pickup(DriverFreightBo driverFreightBo) {
        Date loadingTimeDay = new Date();

        FreightInfo freightInfo = freightInfoMapper.selectById(driverFreightBo.getFreightId());
        freightInfo.setFreightStatus(OrderStatus.DELIVERING.getCode());
        freightInfo.setLoadingTimeDay(loadingTimeDay);
        freightInfo.setLoadingWeight(driverFreightBo.getLoadingWeight());
        freightInfo.setLoadingDriverUrl03(driverFreightBo.getLoadingDriverUrl03());
        freightInfo.setLoadingDriverUrl04(driverFreightBo.getLoadingDriverUrl04());
        freightInfo.setLoadingGoodsUrl01(driverFreightBo.getLoadingGoodsUrl01());
        freightInfo.setLoadingGoodsUrl02(driverFreightBo.getLoadingGoodsUrl02());
        freightInfoMapper.updateById(freightInfo);

        // 更新订单实际取货时间，如果存在就不写入，以第一次为准
        OrderInfo orderInfo = orderInfoMapper.selectById(freightInfo.getOrderId());
        Date loadingTime = orderInfo.getLoadingTimeDay();
        if (ObjectUtil.isNull(loadingTime)) {
            orderInfo.setOrderStatus(OrderStatus.DELIVERING.getCode());
            orderInfo.setLoadingTimeDay(loadingTimeDay);
            orderInfoMapper.updateById(orderInfo);
        }

        // 更新轨迹
        FreightVehicleTrail freightVehicleTrail = new FreightVehicleTrail();
        freightVehicleTrail.setFreightId(driverFreightBo.getFreightId());
        freightVehicleTrail.setLat(driverFreightBo.getDriverLat());
        freightVehicleTrail.setLng(driverFreightBo.getDriverLng());
        freightVehicleTrail.setRelevanceUserId(driverFreightBo.getRelevanceUserId());
        freightVehicleTrail.setIsStartPoint(SysYesNo.Y.name());
        freightVehicleTrail.setRecordTime(DateUtils.getNowDate());
        freightVehicleTrail.setTrail(driverFreightBo.getTrail());
        return freightVehicleTrailMapper.insert(freightVehicleTrail) > 0;
    }

    /**
     * 到货
     *
     * @param driverFreightBo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean discharge(DriverFreightBo driverFreightBo) {
        Date receivingTimeDay = new Date();

        FreightInfo freightInfo = freightInfoMapper.selectById(driverFreightBo.getFreightId());
        freightInfo.setFreightStatus(FreightStatus.WAITING_FOR_RECEIPT.getCode());
        freightInfo.setReceivingTimeDay(receivingTimeDay);
        freightInfo.setReceivingDriverUrl03(driverFreightBo.getReceivingDriverUrl03());
        freightInfo.setReceivingDriverUrl04(driverFreightBo.getReceivingDriverUrl04());
        freightInfo.setReceivingGoodsUrl01(driverFreightBo.getReceivingGoodsUrl01());
        freightInfo.setReceivingGoodsUrl02(driverFreightBo.getReceivingGoodsUrl02());
        freightInfoMapper.updateById(freightInfo);

        // 更新轨迹
        FreightVehicleTrail freightVehicleTrail = new FreightVehicleTrail();
        freightVehicleTrail.setFreightId(driverFreightBo.getFreightId());
        freightVehicleTrail.setLat(driverFreightBo.getDriverLat());
        freightVehicleTrail.setLng(driverFreightBo.getDriverLng());
        freightVehicleTrail.setRelevanceUserId(driverFreightBo.getRelevanceUserId());
        freightVehicleTrail.setRecordTime(DateUtils.getNowDate());
        freightVehicleTrail.setTrail(driverFreightBo.getTrail());
        freightVehicleTrail.setIsEndPoint(SysYesNo.Y.name());
        int result = freightVehicleTrailMapper.insert(freightVehicleTrail);

        // 更新订单实际到货时间
        OrderInfo orderInfo = orderInfoMapper.selectById(freightInfo.getOrderId());
        // 如果是整车，直接更新订单状态
//        if (CarUseType.FTL.getCarUseType().equals(orderInfo.getCarUseType())) {
//            orderInfo.setOrderStatus(OrderStatus.WAITING_FOR_RECEIPT.getCode());
//            orderInfo.setReceivingTimeDay(receivingTimeDay);
//            orderInfoMapper.updateById(orderInfo);
//        } else {
            // 如果是零担，查询当前订单如果是配送中，修改为待回单，往下流转
            // 不是配送中，表明其他运单进度在前，不需更新
        String orderStatus = orderInfo.getOrderStatus();
        if (OrderStatus.DELIVERING.getCode().equals(orderStatus)) {
            List<FreightInfo> freights = freightInfoMapper.selectByOrderId(orderInfo.getOrderId());
            for (FreightInfo freight : freights) {
                // 如果存在运单不是待回单状态，不需要更新订单状态
                if (FreightStatus.fromCode(freight.getFreightStatus()).isBefore(FreightStatus.WAITING_FOR_RECEIPT)) {
                    return result > 0;
                }
            }
            // 更新订单状态
            orderInfo.setOrderStatus(OrderStatus.WAITING_FOR_RECEIPT.getCode());
            orderInfo.setReceivingTimeDay(receivingTimeDay);
            result = orderInfoMapper.updateById(orderInfo);
        }
//        }

        return result > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean receipt(DriverFreightBo driverFreightBo) {
        FreightInfo freightInfo = new FreightInfo();
        freightInfo.setFreightId(driverFreightBo.getFreightId());
        freightInfo.setFreightStatus(FreightStatus.WAITING_FOR_PAYMENT.getCode());
        freightInfoMapper.updateById(freightInfo);

        FreightReceipt freightReceipt = new FreightReceipt();
        freightReceipt.setFreightId(driverFreightBo.getFreightId());
        freightReceipt.setUrl(driverFreightBo.getReceiveImgUrl());
        int result = freightReceiptMapper.insert(freightReceipt);

        // 更新订单状态
        OrderInfo orderInfo = orderInfoMapper.selectById(driverFreightBo.getOrderId());
        // 如果是整车，直接更新订单状态
//        if (CarUseType.FTL.getCarUseType().equals(orderInfo.getCarUseType())) {
//            orderInfo.setOrderStatus(OrderStatus.WAITING_FOR_PAYMENT.getCode());
//            orderInfoMapper.updateById(orderInfo);
//        } else {
            // 如果是零担，查询当前订单是待回单，且所有的运单都是待打款，订单才能流转到待打款
            // 因为需要所有运单都运行到待打款，才能进行打款
        String orderStatus = orderInfo.getOrderStatus();
        if (OrderStatus.WAITING_FOR_RECEIPT.getCode().equals(orderStatus)) {
            List<FreightInfo> freights = freightInfoMapper.selectByOrderId(orderInfo.getOrderId());
            for (FreightInfo freight : freights) {
                // 如果存在运单在待打款之前，不需要更新订单状态
                if (FreightStatus.fromCode(freight.getFreightStatus()).isBefore(FreightStatus.WAITING_FOR_PAYMENT)) {
                    return result > 0;
                }
            }
            // 更新订单状态
            orderInfo.setOrderStatus(OrderStatus.WAITING_FOR_PAYMENT.getCode());
            result = orderInfoMapper.updateById(orderInfo);
        }
//        }

        return result > 0;
    }

    @Override
    public Boolean insertByBo(DriverFreightBo driverFreightBo) {
        // 更新轨迹
        FreightVehicleTrail freightVehicleTrail = new FreightVehicleTrail();
        freightVehicleTrail.setFreightId(driverFreightBo.getFreightId());
        freightVehicleTrail.setLat(driverFreightBo.getDriverLat());
        freightVehicleTrail.setLng(driverFreightBo.getDriverLng());
        freightVehicleTrail.setRecordTime(DateUtils.getNowDate());
        freightVehicleTrail.setRelevanceUserId(driverFreightBo.getRelevanceUserId());
        freightVehicleTrail.setTrail(driverFreightBo.getTrail());
        return freightVehicleTrailMapper.insert(freightVehicleTrail) > 0;
    }

    @Override
    public Boolean checkFreightStatus(Long freightId, String freightStatus) {
        FreightInfo freightInfo = freightInfoMapper.selectById(freightId);
        if (freightInfo == null) {
            return false;
        }
        return freightStatus.equals(freightInfo.getFreightStatus());
    }

    @Override
    public TableDataInfo<OrderFreightInfoVo> selectOrderFrightPage(Long relevanceUserId,
                                                                   List<String> freightStatusList,
                                                                   PageQuery pageQuery) {
        LambdaQueryWrapper<FreightInfo> lqw = new LambdaQueryWrapper();
        lqw.eq(FreightInfo::getRelevanceUserId, relevanceUserId)
            .in(CollectionUtils.isNotEmpty(freightStatusList), FreightInfo::getFreightStatus, freightStatusList)
            .orderByDesc(FreightInfo::getUpdateTime);

        Page<FreightInfo> freightPages = freightInfoMapper.selectPage(pageQuery.build(), lqw);
        if (CollectionUtils.isEmpty(freightPages.getRecords())) {
            return TableDataInfo.build(Collections.emptyList());
        }

        List<Long> orderIds = freightPages.getRecords().stream()
            .map(FreightInfo::getOrderId)
            .collect(Collectors.toList());
        List<OrderInfo> orderInfos = orderInfoMapper.selectBatchIds(orderIds);
        // 将 orderInfos 转换为 Map
        Map<Long, OrderInfo> orderInfoMap = orderInfos.stream()
            .collect(Collectors.toMap(OrderInfo::getOrderId, Function.identity()));

        IPage<OrderFreightInfoVo> pageVo = freightPages.convert(freightPage -> {
            OrderFreightInfoVo orderFreightInfoVo = new OrderFreightInfoVo();
            orderFreightInfoVo.setDriverFreightVo(BeanCopyUtils.copy(freightPage, DriverFreightVo.class));

            // 从Map中获取对应的OrderInfo
            OrderInfo orderInfo = orderInfoMap.get(freightPage.getOrderId());
            if (orderInfo != null) {
                orderFreightInfoVo.setDriverOrderVo(BeanCopyUtils.copy(orderInfo, DriverOrderVo.class));
            }
            return orderFreightInfoVo;
        });

        return TableDataInfo.build(pageVo);
    }
}
